﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Runtime.Serialization;

namespace Ice.ChinaKnowledge.Data
{
    [Serializable]
    public class DataTransfer : ISerializable
    {
        protected Dictionary<string, object> keyValues = new Dictionary<string, object>();

        #region /* Serializable */

        protected DataTransfer(SerializationInfo info, StreamingContext context)
        {
            foreach (var entry in info)
            {
                keyValues.Add(entry.Name, entry.Value);
            }
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            foreach (string k in keyValues.Keys)
            {
                info.AddValue(k, keyValues[k], keyValues[k] == null ? typeof(object) : keyValues[k].GetType());
            }
        }

        #endregion

        /// <summary>
        /// 返回字段数量
        /// </summary>
        public int FieldCount { get { return keyValues.Count; } }
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public DataTransfer() { }
        /// <summary>
        /// 构造函数,填充一个数据源
        /// </summary>
        /// <param name="dataReader"></param>
        public DataTransfer(IDataReader dataReader)
        {
            Fill(dataReader);
        }
        /// <summary>
        /// 构造函数,填充一个字典类
        /// </summary>
        /// <param name="dictionary"></param>
        public DataTransfer(IDictionary<string, object> dictionary)
        {
            Fill(dictionary);
        }
        /// <summary>
        /// 填充数据
        /// </summary>
        /// <param name="dataReader">数据源</param>
        public void Fill(IDataReader dataReader)
        {
            if (dataReader == null) throw new Exception("The object can not be empty.");

            for (int i = 0; i < dataReader.FieldCount; i++)
            {
                keyValues.Add(dataReader.GetName(i), dataReader.GetValue(i));
            }
        }
        /// <summary>
        /// 填充数据
        /// </summary>
        /// <param name="dictionary">数据源</param>
        public void Fill(IDictionary<string, object> dictionary)
        {
            if (dictionary == null) throw new Exception("The object can not be empty.");

            foreach (var item in dictionary)
            {
                keyValues.Add(item.Key, item.Value);
            }
        }
        /// <summary>
        /// 填充数据
        /// </summary>
        /// <param name="dataTransfer">数据源</param>
        public void Fill(DataTransfer dataTransfer)
        {
            var keys = dataTransfer.Keys();

            for (var i = 0; i < dataTransfer.FieldCount; i++)
            {
                keyValues.Add(keys[i], dataTransfer[keys[i]]);
            }
        }
        /// <summary>
        /// 根据键获取值，这是一个范型方法，可以把值自动转换想要的类型。
        /// </summary>
        /// <typeparam name="TValue">值类型</typeparam>
        /// <param name="key">Key</param>
        /// <returns>Value</returns>
        public TValue DefaultValue<TValue>(string key)
        {
            if (!keyValues.ContainsKey(key)) return default(TValue);

            return (TValue)(Convert.ChangeType(this[key], typeof(TValue)));
        }
        /// <summary>
        /// 添加键值对
        /// </summary>
        /// <param name="key">Key</param>
        /// <param name="value">Value</param>
        public void AddKeyValue(string key, object value)
        {
            keyValues.Add(key, value);
        }
        /// <summary>
        /// 删除键值对
        /// </summary>
        /// <param name="key">Key</param>
        public void RemoveKeyValue(string key)
        {
            keyValues.Remove(key);
        }
        /// <summary>
        /// 所引器，根据Key返回一个Object类型的值
        /// </summary>
        /// <param name="key">Key</param>
        /// <returns>Value</returns>
        public object this[string key]
        {
            get { return keyValues.ContainsKey(key) ? keyValues[key] : null; }
            set { keyValues[key] = value; }
        }
        /// <summary>
        /// 返回所有键
        /// </summary>
        /// <returns></returns>
        public string[] Keys() 
        { 
            return keyValues.Keys.ToArray(); 
        }
        /// <summary>
        /// 返回所有值
        /// </summary>
        /// <returns></returns>
        public object[] Values() 
        { 
            return keyValues.Values.ToArray(); 
        }
        /// <summary>
        /// 重写了ToString方法，返回对像的JSON字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            var strKeyValues = keyValues
                .Select(o => String.Format("\"{0}\":\"{1}\"", o.Key, o.Value))
                .ToArray();

            return "{" + String.Join(",", strKeyValues) + "}";
        }
    }
}
